package com.itheima.thread;

import java.util.ArrayList;
import java.util.function.Consumer;

/**
 * @author zzy
 * @date 2023/4/6 14:28
 * 1). 有多个线程，一个线程为生产者，其他线程为消费者；
 * 2). 生产者生产商品，未消费的商品达到 20 件时就休息，小于 20 件时就继续生产；
 * 3). 消费者消费商品，当没有可消费的商品时就休息，有可消费的商品时就继续消费；
 * 4). 主入口函数 main 的输入参数有 3 个，分别为：消费者线程个数，生产速度（件/秒），消费速度（件/秒）。
 * 例如消费者线程个数为 2，生产速度为 8（即每 125 ms 生产 1 件商品），消费速度为 3（即每 1000/3 ms 消费 1 件商品）
 */

public class Product {
    private static ArrayList<Integer> product = new ArrayList<Integer>();
    private static Object obj = new Object();

    public static void main(String[] args) {
        System.out.println("开始启动线程");
        startProduct( 2,8,3);
    }

    private static void startProduct(int consumerSize,int produceSpeed,int consumerSpeed){
        //启动生产者
        new Producer(produceSpeed).start();
        //启动消费者
        for(int i=1;i<=consumerSize;i++){
            new Consumer(i,consumerSpeed).start();
        }
        System.exit(0);
    }

    private static class Producer extends Thread{
        int n;//生产速度
        int i;//生产者所有生产的第几个商品
        Producer(int n){
            this.n=n;
        }

        @Override
        public void run() {

            while(true){
                try {
                    Thread.sleep(1000/n);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj) {
                    if(product.size()==20){
                        try {
                            System.out.println("生产商品达到20，停止生产！！");
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        int num = 10000+i++;
                        product.add(num);
                        System.out.println("生产者生产了商品，商品编号"+num);
                        obj.notifyAll();
                    }
                }
            }
        }
    }

    private static class Consumer extends Thread{
        int n;//消费者数
        int speed;//消费速度
        Consumer(int n,int speed){
            this.n=n;
            this.speed =speed;
        }

        @Override
        public void run() {
            while(true){
                try {
                    Thread.sleep(1000/speed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj) {
                    if(product.size()==0){
                        try {
                            System.out.println("商品已消费完！！");
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        Integer a = product.remove(0);
                        System.out.println("消费者"+n+"消费了商品"+a);
                        obj.notifyAll();
                    }
                }
            }
        }
    }

}
